package com.zytlifeservice.service.pay;

import com.qianmi.open.api.ApiException;
import com.qianmi.open.api.domain.elife.AdminItem;
import com.qianmi.open.api.request.BmDirectRechargeGhkdItemListRequest;
import com.qianmi.open.api.request.BmDirectRechargeGhkdPayBillRequest;
import com.qianmi.open.api.response.BmDirectRechargeGhkdItemListResponse;
import com.qianmi.open.api.response.BmDirectRechargeGhkdPayBillResponse;
import com.zytlifeservice.domain.User;
import com.zytlifeservice.domain.pay.AlipayOrder;
import com.zytlifeservice.domain.pay.BaseQmOrder;
import com.zytlifeservice.domain.pay.BroadBandAndPhoneDomain;
import com.zytlifeservice.domain.pay.WxPayOrder;
import com.zytlifeservice.exception.UserException;
import com.zytlifeservice.repository.UserRepository;
import com.zytlifeservice.repository.pay.AlipayOrderRepository;
import com.zytlifeservice.repository.pay.BroadBandAndPhoneRepository;
import com.zytlifeservice.repository.pay.WxPayOrderRepository;
import com.zytlifeservice.util.TextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by MJS on 2017/5/31.
 */

@Service
public class BroadBandAndPhoneService {

    //后期封装进spring容器内，保证单例
    private static final Logger logger = LoggerFactory.getLogger(BroadBandAndPhoneService.class);

    @Autowired
    UserRepository userRepository;

    @Autowired
    AlipayOrderRepository alipayOrderRepository;

    @Autowired
    WxPayService wxPayService;

    @Autowired
    BroadBandAndPhoneRepository broadBandAndPhoneRepository;

    @Autowired
    WxPayOrderRepository wxPayOrderRepository;

    @Autowired
    AlipayService alipayService;

    @Autowired
    PublicService publicService;

    public List<Map<String, Object>> queryInfoByAddress(String address) {
        BmDirectRechargeGhkdItemListRequest req = new BmDirectRechargeGhkdItemListRequest();
        req.setPageSize(30);
        if (!TextUtil.isEmpty(address)) {
            req.setItemName(address);  //这里支持模糊查询
        }
        try {
            BmDirectRechargeGhkdItemListResponse response = publicService.execute(req);
            List<AdminItem> items = response.getItems();
            if (items == null || items.size() == 0) {
                //这里没有请求到数据。提示该地区尚未开通此服务
                return null;
            }
            List<Map<String, Object>> mapList = new ArrayList<>();

            for (AdminItem item : items) {
                String itemId = item.getItemId();
                String itemName = item.getItemName();
                String[] params = itemName.replaceAll("\\s{1,}", " ").split(" ");

                //过滤账号类型。只添加宽带的类型。
                String type = params[params.length - 2];
                if (!"宽带".equals(type)) {
                    continue;
                }

                String name = params[1];
                String costStr = params[params.length - 1];
                costStr = costStr.replace("元", "");
                String cost = costStr.substring(2);
                Map<String, Object> contain = contain(mapList, name);
                if (contain != null) {
                    List<Item> list = (List<Item>) contain.get("itemArr");
                    if (costStr.contains("任意充") && isHold(list)) {  //多个任意充只处理一个。
                        continue;
                    }
                    list.add(new Item(itemId, cost));
                } else {
                    Map<String, Object> curBean = new HashMap<>();
                    curBean.put("itemName", name);
                    List<Item> list = new ArrayList<>();
                    list.add(new Item(itemId, cost));
                    curBean.put("itemArr", list);
                    mapList.add(curBean);
                }
            }
            return mapList;
        } catch (ApiException e) {
            throw new UserException("查询失败，请稍后重试", 202);
        }
    }

    private boolean isHold(List<Item> list) {
        boolean isHold = false;
        for (Item bean : list) {
            if (bean.getMoney().contains("任意充")) {
                isHold = true;
                break;
            }
        }
        return isHold;
    }

    private Map<String, Object> contain(List<Map<String, Object>> mapList, String name) {
        for (Map<String, Object> map : mapList) {
            if (map.containsValue(name)) {
                return map;
            }
        }
        return null;
    }

    //下订单
    public String[] createOrder(String itemId, String account, String rechargeAmount, String address, String itemName, Long userId) {
        String[] res = new String[2];
        User one = userRepository.findOne(userId);
        if (one == null) {
            throw new UserException("用户不存在", 202);
        }
        //生成aliOrder
        AlipayOrder alipayOrder = new AlipayOrder();
        alipayOrder.setStoreId(one.getStoreId());
        alipayOrder.setSubject(itemName);//对应的后台的信息
        String outTradeNo = "zyt" + userId + System.currentTimeMillis()   //添加userId
                + (long) (Math.random() * 10000000L);
        alipayOrder.setOutTradeNo(outTradeNo);
        alipayOrder.setTotalAmount(rechargeAmount);
        alipayOrder.setUserId(userId);
        alipayOrder.setType(AlipayOrder.TYPE_GHKD_RECHARGE);
        alipayOrderRepository.save(alipayOrder);

        //生成千米订单
        BroadBandAndPhoneDomain bandAndPhoneOrder = new BroadBandAndPhoneDomain();
        publicService.setBaseOrderType(bandAndPhoneOrder);
        bandAndPhoneOrder.setRechargeAccount(account);
        bandAndPhoneOrder.setAddress(address);
        bandAndPhoneOrder.setItemId(itemId);
        bandAndPhoneOrder.setOutTradeNo(outTradeNo);
        bandAndPhoneOrder.setItemName(itemName);  //联通话费+充值金额
        bandAndPhoneOrder.setUserId(userId);
        bandAndPhoneOrder.setSaleAmount(rechargeAmount);
        bandAndPhoneOrder.setPayType(BaseQmOrder.PAY_TYPE_ALIPAY);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        bandAndPhoneOrder.setOrderTime(sdf.format(new Date()));
        bandAndPhoneOrder.setPayState("0");  //这里修改其状态。
        bandAndPhoneOrder.setPayResult(BaseQmOrder.STATUS_INIT);
        if (!publicService.querySum(rechargeAmount)) {
            bandAndPhoneOrder.setFailReason("直销商余额不足,取消支付宝预下单");
            broadBandAndPhoneRepository.save(bandAndPhoneOrder);
            res[0] = "fail";
            res[1] = "直销商余额不足,取消支付宝预下单";
            return res;
        }
        broadBandAndPhoneRepository.save(bandAndPhoneOrder);
        res[0] = "success";
        res[1] = alipayService.pay(alipayOrder) + "," + outTradeNo;
        return res;
    }

    public String[] wxPreCreateOrder(String itemId, String account, String rechargeAmount, String address, String itemName, Long userId, String ip) {
        String[] res = new String[2];
        User one = userRepository.findOne(userId);
        if (one == null) {
            throw new UserException("用户不存在", 202);
        }

        String outTradeNo = "zyt" + userId + System.currentTimeMillis()   //添加userId
                + (long) (Math.random() * 10000000L);
        WxPayOrder wxPayOrder = publicService.generateWxpayOrder(one, itemName, ip, rechargeAmount, outTradeNo,
                WxPayOrder.TYPE_GHKD_RECHARGE);
        wxPayOrderRepository.save(wxPayOrder);

        BroadBandAndPhoneDomain bandAndPhoneOrder = new BroadBandAndPhoneDomain();
        publicService.setBaseOrderType(bandAndPhoneOrder);
        bandAndPhoneOrder.setRechargeAccount(account);
        bandAndPhoneOrder.setAddress(address);
        bandAndPhoneOrder.setItemId(itemId);
        bandAndPhoneOrder.setOutTradeNo(outTradeNo);
        bandAndPhoneOrder.setItemName(itemName);
        bandAndPhoneOrder.setUserId(userId);
        bandAndPhoneOrder.setPayType(BaseQmOrder.PAY_TYPE_WXPAY);
        bandAndPhoneOrder.setSaleAmount(rechargeAmount);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        bandAndPhoneOrder.setOrderTime(sdf.format(new Date()));
        bandAndPhoneOrder.setPayState("0");  //这里修改其状态。
        bandAndPhoneOrder.setPayResult(BaseQmOrder.STATUS_INIT);
        if (!publicService.querySum(rechargeAmount)) {
            bandAndPhoneOrder.setFailReason("直销商余额不足,取消支付宝预下单");
            broadBandAndPhoneRepository.save(bandAndPhoneOrder);
            res[0] = "fail";
            res[1] = "直销商余额不足,取消支付宝预下单";
            return res;
        }
        broadBandAndPhoneRepository.save(bandAndPhoneOrder);
        res[0] = "success";
        res[1] = wxPayService.pay(wxPayOrder) + "," + outTradeNo;
        return res;
    }

    public String pay(String outTradeNo) {
        BroadBandAndPhoneDomain order = broadBandAndPhoneRepository.findByOutTradeNo(outTradeNo);
        logger.error("宽带order={}", order);
        BmDirectRechargeGhkdPayBillRequest req = new BmDirectRechargeGhkdPayBillRequest();
        req.setItemId(order.getItemId());
        req.setAccount(order.getRechargeAccount());
        req.setOuterTid(order.getOutTradeNo());
        req.setCallback(publicService.getBmCallbackUrl());
//        if (!TextUtil.isEmpty(order.getSaleAmount())) {
//            req.setItemNum(order.getSaleAmount());
//        }
        try {
            BmDirectRechargeGhkdPayBillResponse response = publicService.execute(req);
            if (!response.isSuccess()) {
                order.setFailReason(response.getSubMsg());
                order.setPayResult(BaseQmOrder.STATUS_FAIL);
                broadBandAndPhoneRepository.save(order);

                if (order.getPayType() == BaseQmOrder.PAY_TYPE_ALIPAY) {
                    AlipayOrder byOutTradeNo = alipayOrderRepository.findByOutTradeNo(outTradeNo);
                    byOutTradeNo.setRefundReason(response.getSubMsg());
                    return alipayService.reFund(byOutTradeNo,"");
                } else if (order.getPayType() == BaseQmOrder.PAY_TYPE_WXPAY) {
                    WxPayOrder wxPayOrder = wxPayOrderRepository.findByOutTradeNo(outTradeNo);
                    wxPayOrder.setRefundReason(response.getSubMsg());
                    return wxPayService.refund(wxPayOrder,"");
                }
            }
            publicService.parseResponse(order, response.getOrderDetailInfo());
            broadBandAndPhoneRepository.save(order);
        } catch (ApiException e) {
            order.setFailReason(e.getMessage());
            order.setPayResult(BaseQmOrder.STATUS_FAIL);
            broadBandAndPhoneRepository.save(order);
            if (order.getPayType() == BaseQmOrder.PAY_TYPE_ALIPAY) {
                AlipayOrder byOutTradeNo = alipayOrderRepository.findByOutTradeNo(outTradeNo);
                byOutTradeNo.setRefundReason(e.getMessage());
                return alipayService.reFund(byOutTradeNo,"");
            } else if (order.getPayType() == BaseQmOrder.PAY_TYPE_WXPAY) {
                WxPayOrder wxPayOrder = wxPayOrderRepository.findByOutTradeNo(outTradeNo);
                wxPayOrder.setRefundReason(e.getMessage());
                return wxPayService.refund(wxPayOrder,"");
            }
            e.printStackTrace();
            throw new UserException("付款失败", 202);
        }
        return "error";
    }


    class Item {
        private String itemId;
        private String money;

        public Item(String itemId, String money) {
            this.itemId = itemId;
            this.money = money;
        }

        public String getItemId() {
            return itemId;
        }

        public void setItemId(String itemId) {
            this.itemId = itemId;
        }

        public String getMoney() {
            return money;
        }

        public void setMoney(String money) {
            this.money = money;
        }
    }
}
